package com.gang.mars.basic.generictype.demo9.annotation;

import com.gang.mars.basic.generictype.demo9.selectors.GangMergedAnnotationSelector;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Iterator;
import java.util.function.Predicate;

/**
 * @Author：gang.chen
 * @Date：2023/6/19 8:38
 */
public class GangTypeMappedAnnotations implements GangMergedAnnotations{

    private final AnnotatedElement element;

    public GangTypeMappedAnnotations(AnnotatedElement element) {
        this.element = element;
    }


    @Override
    public <A extends GangAnnotation> GangMergedAnnotation<A> get(Class<A> annotationType) {
        return null;
    }


    /**
     * @param selector 该实例里泛型参数实例为: GangAnnotation
     * */
    @Override
    public <A extends GangAnnotation> GangMergedAnnotation<A> get(String annotationType, Predicate<? super GangMergedAnnotation<A>> predicate, GangMergedAnnotationSelector<A> selector) {
        if (false)
        {
            //TODO
        }

        /**
         * 指定 C -> Object
         * 指定 R -> GangMergedAnnotation
         *
         * 当该对象输入指定方法后，方法的C/R就指定了
         * */
        GangMergedAnnotationFinder<A> mergedAnnotationFinder = new GangMergedAnnotationFinder<>(annotationType, predicate, selector);

        GangMergedAnnotation<A> mergedAnnotation = scan(annotationType, mergedAnnotationFinder);

        return mergedAnnotation;
    }

    /**
     * @param criteria ; Object->String
     * @param processor; GangMergedAnnotationFinder
     *
     * return GangMergedAnnotation<GangAnnotation>
     * */
    private <C, R> R scan(C criteria, GangAnnotationsProcessor<C, R> processor){

        if (false)
        {
            // TODO
        }
        if (true)
        {
            return GangAnnotationsScanner.scan(criteria, null, null, processor);
        }
        return null;
    }



    @Override
    public Iterator<GangMergedAnnotation<GangAnnotation>> iterator() {
        return null;
    }


    /**
     * Object -> C
     * GangMergedAnnotation<A> -> R
     * */
    private class GangMergedAnnotationFinder<A extends GangAnnotation> implements GangAnnotationsProcessor<Object, GangMergedAnnotation<A>>
    {

        private final Object requiredType;
        private final Predicate<? super GangMergedAnnotation<A>> predicate;
        private final GangMergedAnnotationSelector<A> selector;

        private GangMergedAnnotationFinder(Object requiredType, Predicate<? super GangMergedAnnotation<A>> predicate, GangMergedAnnotationSelector<A> selector) {
            this.requiredType = requiredType;
            this.predicate = predicate;
            this.selector = selector;
        }

        @Override
        public GangMergedAnnotation<A> doWithAnnotations(Object type, int aggregateIndex, Object source, Annotation[] annotations) {

            for (Annotation annotation : annotations) {

                GangMergedAnnotation<A> process = process(type, aggregateIndex, source, annotation);

            }
            return null;
        }

        private GangMergedAnnotation<A> process(Object type, int aggregateIndex, Object source, Annotation annotation)
        {
            return null;
        }
    }
}
